package exam.system.dao;

import java.util.HashMap;
import java.util.List;

import org.hibernate.HibernateException;

import exam.common.util.NullCheckUtil;

public class AbstractDAO<T> implements MethodDaoBase<T> {
	/**
	 * jdbcManager
	 */
	protected JdbcManager<T> jdbcManager = new JdbcManager<T>();
		
	/**
	 * entityClass:Class
	 */
	private Class<T> entityClass;
	
	/**
	 * constructor
	 * @param entity
	 */
	public AbstractDAO(Class<T> entity) {
		this.entityClass = entity;
	}
	
	@Override
	public List<T> selectList(String query) {
		// TODO Auto-generated method stub
		List<T> list = null;
		try {
			jdbcManager.beginTransaction();
			list = jdbcManager.executeByQuery(query).getListResult();
			jdbcManager.commit();
		} catch (HibernateException e) {
			if(NullCheckUtil.isNotNull(jdbcManager.transaction)) {
				jdbcManager.rollBack();
			}
			e.printStackTrace();
		} finally {
			jdbcManager.closeSession();
		}
		return list;
	}
	
	@Override
	public T selectByPk(long id) {
		T entity = null;
		try {
			jdbcManager.beginTransaction();
			entity = jdbcManager.selectByEntityClass(entityClass, id);
			jdbcManager.commit();
		} catch (HibernateException e) {
			if(NullCheckUtil.isNotNull(jdbcManager.transaction)) {
				jdbcManager.rollBack();
			}
			e.printStackTrace();
		} finally {
			jdbcManager.closeSession();
		}
		return entity;
	}

	@Override
	public void delete(long id) {
		// TODO Auto-generated method stub
		try {
			jdbcManager.beginTransaction();
			jdbcManager.delete(entityClass, id);
			jdbcManager.commit();
		} catch (HibernateException e) {
			if(NullCheckUtil.isNotNull(jdbcManager.transaction)) {
				jdbcManager.rollBack();
			}
			e.printStackTrace();
		} finally {
			jdbcManager.closeSession();
		}
	}

	@Override
	public int insert(T entity) {
		// TODO Auto-generated method stub
		int rs = 0;
		try {
			jdbcManager.beginTransaction();
			rs = jdbcManager.insert(entity).intValue();
			jdbcManager.commit();
		} catch (HibernateException e) {
			if(NullCheckUtil.isNotNull(jdbcManager.transaction)) {
				jdbcManager.commit();
			}
			e.printStackTrace();
		} finally {
			jdbcManager.closeSession();
		}
		return rs;
	}

	@Override
	public void update(T entity) {
		// TODO Auto-generated method stub
		try {
			jdbcManager.beginTransaction();
			jdbcManager.update(entity);
			jdbcManager.commit();
		} catch (HibernateException e) {
			if(NullCheckUtil.isNotNull(jdbcManager.transaction)) {
				jdbcManager.rollBack();
			}
			e.printStackTrace();
			System.err.println(entity.getClass().getName() + "#update");
		} finally {
			jdbcManager.closeSession();
		}
	}
	
	/**
	 * updateByQuery
	 * @param query
	 * @param params
	 * @return int
	 */
	public int updateByQueryParams(String query, HashMap<String, Object> params) {
		int rs = 0;
		try {
			jdbcManager.beginTransaction();
			rs = jdbcManager.executeByQueryParams(query, params).getInt();
			jdbcManager.commit();
		} catch (HibernateException e) {
			if(NullCheckUtil.isNotNull(jdbcManager.transaction)) {
				jdbcManager.rollBack();
			}
			e.printStackTrace();
		} finally {
			jdbcManager.closeSession();
		}
		return rs;
	}
	
	/**
	 * deleteByQuery
	 * @param query
	 * @param params
	 * @return
	 */
	public int deleteByQueryParams(String query, HashMap<String, Object> params) {
		int rs = 0;
		try {
			jdbcManager.beginTransaction();
			rs = jdbcManager.executeByQueryParams(query, params).getInt();
			jdbcManager.commit();
		} catch (HibernateException e) {
			if(NullCheckUtil.isNotNull(jdbcManager.transaction)) {
				jdbcManager.rollBack();
			}
			e.printStackTrace();
		} finally {
			jdbcManager.closeSession();
		}
		return rs;
	}
	
	/**
	 * selectByQuery
	 * @param query
	 * @param params
	 * @return
	 */
	public Object selectByQueryParams(String query, HashMap<String, Object> params) {
		Object obj = null;
		try {
			jdbcManager.beginTransaction();
			obj = jdbcManager.executeByQueryParams(query, params).getObjectResult();
			jdbcManager.commit();
		} catch (HibernateException e) {
			if(NullCheckUtil.isNotNull(jdbcManager.transaction)) {
				jdbcManager.rollBack();
			}
			e.printStackTrace();
		} finally {
			jdbcManager.closeSession();
		}
		return obj;
	}
}
